package com.dragon.backstage.listener;

import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * SaToken后台全局侦听器
 *
 * @author dragon
 * @version 1.0
 * @date 2024/10/19 16:09
 */
@Slf4j
@Component
public class SaTokenBackstageListener implements SaTokenListener {

    @Resource
    private ObjectMapper objectMapper;


    /** 每次登录时触发 */
    @Override
    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
        log.info("SaToken后台全局侦听器 账号 {} 登录成功 (loginType={}), 会话凭证Token={}", loginId, loginType, tokenValue);
    }

    /** 每次注销时触发 */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        log.info("SaToken后台全局侦听器 账号 {} 注销登录 (loginType={}), 会话凭证Token={}", loginId, loginType, tokenValue);

        SaSession saSession = StpUtil.getTokenSessionByToken(tokenValue);
        if (Objects.nonNull(saSession)) {
            saSession.clear();
        }
    }

    /** 每次被踢下线时触发 */
    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        log.info("SaToken后台全局侦听器 账号 {} 被踢下线 (loginType={}), 会话凭证Token={}", loginId, loginType, tokenValue);

        SaSession saSession = StpUtil.getTokenSessionByToken(tokenValue);
        if (Objects.nonNull(saSession)) {
            saSession.clear();
        }
    }

    /** 每次被顶下线时触发 */
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {
        log.info("SaToken后台全局侦听器 账号 {} 被顶下线 (loginType={}), 会话凭证Token={}", loginId, loginType, tokenValue);

        SaSession saSession = StpUtil.getTokenSessionByToken(tokenValue);
        if (Objects.nonNull(saSession)) {
            saSession.clear();
        }
    }

    /** 每次被封禁时触发 */
    @Override
    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
        log.info("SaToken后台全局侦听器 账号 {} [{}服务] 被封禁 (loginType={}), 封禁等级={}, 解封时间为 {}", loginId, loginType, service, level, SaFoxUtil.formatAfterDate(disableTime * 1000L));
    }

    /** 每次被解封时触发 */
    @Override
    public void doUntieDisable(String loginType, Object loginId, String service) {
        log.info("SaToken后台全局侦听器 账号 {} [{}服务] 解封成功 (loginType={})", loginId, service, loginType);
    }

    /** 每次二级认证时触发 */
    @Override
    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
        log.info("SaToken后台全局侦听器 Token 二级认证成功, 业务标识={}, 有效期={}秒, Token值={}", service, safeTime, tokenValue);
    }

    /** 每次退出二级认证时触发 */
    @Override
    public void doCloseSafe(String loginType, String tokenValue, String service) {
        log.info("SaToken后台全局侦听器 Token 二级认证关闭, 业务标识={}, Token值={}", service, tokenValue);
    }

    /** 每次创建Session时触发 */
    @Override
    public void doCreateSession(String id) {
        log.info("SaToken后台全局侦听器 SaSession [{}] 创建成功", id);
    }

    /** 每次注销Session时触发 */
    @Override
    public void doLogoutSession(String id) {
        log.info("SaToken后台全局侦听器 SaSession [{}] 注销成功", id);
    }

    /** 每次Token续期时触发 */
    @Override
    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
        log.info("SaToken后台全局侦听器 Token 续期成功, {} 秒后到期, 帐号={}, Token值={} ", timeout, loginId, tokenValue);
    }

}
